<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>IndexedDB 任务列表</title>
  </head>
  <body>
    <h1>IndexedDB 任务管理</h1>

    <!-- 添加任务区域 -->
    <input type="text" id="taskInput" placeholder="输入任务名称" />
    <button id="addTaskButton">添加任务</button>

    <hr />

    <!-- 操作任务列表 -->
    <button id="loadTasksButton">加载任务列表</button>

    <ul id="taskList"></ul>

    <script>
      const dbName = 'TaskDatabase' // 数据库名称
      const storeName = 'Tasks' // 对象存储名称
      let db // 数据库实例

      // 初始化数据库
      const request = indexedDB.open(dbName, 1) // 打开数据库，版本号为 1

      // 数据库初始化成功或版本更新时触发
      request.onupgradeneeded = function (event) {
        db = event.target.result // 获取数据库实例
        // 如果对象存储不存在，则创建一个新的对象存储
        if (!db.objectStoreNames.contains(storeName)) {
          db.createObjectStore(storeName, { keyPath: 'id', autoIncrement: true }) // 设置主键为 id，自增
        }
        console.log('数据库初始化成功')
      }

      // 数据库打开成功时触发
      request.onsuccess = function (event) {
        db = event.target.result // 获取数据库实例
        console.log('数据库打开成功')
      }

      // 数据库打开失败时触发
      request.onerror = function (event) {
        console.error('数据库打开失败', event)
      }

      // 添加任务
      function addTask(taskName) {
        const transaction = db.transaction(storeName, 'readwrite') // 创建一个读写事务
        const store = transaction.objectStore(storeName) // 获取对象存储
        const task = { name: taskName, created: new Date().toISOString() } // 创建任务对象
        const request = store.add(task) // 将任务添加到对象存储

        // 任务添加成功时触发
        request.onsuccess = function () {
          console.log('任务添加成功', task)
        }

        // 任务添加失败时触发
        request.onerror = function (event) {
          console.error('任务添加失败', event)
        }
      }

      // 显示任务列表
      function displayTasks() {
        const transaction = db.transaction(storeName, 'readonly') // 创建一个只读事务
        const store = transaction.objectStore(storeName) // 获取对象存储
        const request = store.getAll() // 获取所有任务

        // 获取任务成功时触发
        request.onsuccess = function (event) {
          const tasks = event.target.result // 获取任务数据
          const taskList = document.getElementById('taskList') // 获取任务列表容器
          taskList.innerHTML = '' // 清空当前列表

          // 遍历任务并显示到页面上
          tasks.forEach((task) => {
            const li = document.createElement('li') // 创建列表项
            li.textContent = `${task.name} (创建时间: ${task.created})` // 设置任务内容

            const deleteButton = document.createElement('button') // 创建删除按钮
            deleteButton.textContent = '删除' // 按钮文字
            deleteButton.onclick = () => deleteTask(task.id) // 绑定删除事件
            li.appendChild(deleteButton) // 将按钮添加到列表项

            taskList.appendChild(li) // 将列表项添加到任务列表
          })
        }

        // 获取任务失败时触发
        request.onerror = function (event) {
          console.error('任务加载失败', event)
        }
      }

      // 删除任务
      function deleteTask(taskId) {
        const transaction = db.transaction(storeName, 'readwrite') // 创建一个读写事务
        const store = transaction.objectStore(storeName) // 获取对象存储
        const request = store.delete(taskId) // 删除指定任务

        // 任务删除成功时触发
        request.onsuccess = function () {
          console.log('任务删除成功', taskId)
          displayTasks() // 刷新任务列表
        }

        // 任务删除失败时触发
        request.onerror = function (event) {
          console.error('任务删除失败', event)
        }
      }

      // 事件绑定：添加任务按钮
      document.getElementById('addTaskButton').onclick = function () {
        const taskInput = document.getElementById('taskInput') // 获取任务输入框
        const taskName = taskInput.value.trim() // 获取并去除输入内容的空格
        if (taskName) {
          addTask(taskName) // 添加任务
          taskInput.value = '' // 清空输入框
        } else {
          alert('请输入任务名称！') // 提示用户输入任务名称
        }
      }

      // 事件绑定：加载任务列表按钮
      document.getElementById('loadTasksButton').onclick = function () {
        displayTasks() // 加载并显示任务列表
      }
    </script>
  </body>
</html>